package com.lagou.filter;

import com.lagou.util.MonitorData;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;

import java.util.concurrent.ConcurrentHashMap;

@Activate(group = CommonConstants.CONSUMER)
public class TPMonitorFilter implements Filter {
    /**
     * 缓存每个方法的调用情况
     */
    private static ConcurrentHashMap<String, MonitorData> concurrentHashMap = new ConcurrentHashMap<>();

    /**
     * 上次计算时刻
     */
    private static long lastCalculateTime = 0;

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        //调用方法，记录执行前后时间
        Long startTime = System.currentTimeMillis();
        Result result = invoker.invoke(invocation);
        Long endTime = System.currentTimeMillis();

        //每个方法一个MonitorData
        String methodName = invocation.getMethodName();
        MonitorData monitorData = concurrentHashMap.get(methodName);
        if (monitorData == null) {
            monitorData = new MonitorData();
        }
        concurrentHashMap.put(methodName, monitorData);

        //缓存每次调用耗时
        Long ms = (endTime - startTime);
        monitorData.addTime(ms.intValue());

        //每五秒计算一次
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastCalculateTime >= 5000) {
            lastCalculateTime = currentTime;

            /**
             * TP50
             */
            int tp50 = monitorData.countTP(0.5F);
            /**
             * TP90
             */
            int tp90 = monitorData.countTP(0.9F);
            /**
             * TP95
             */
            int tp95 = monitorData.countTP(0.95F);

            System.out.println("方法" + methodName + "性能如下：");
            System.out.println("TP50:" + tp50);
            System.out.println("TP90:" + tp90);
            System.out.println("TP95:" + tp95);
        }
        return result;
    }

}
